package com.base.cn.platform.os.service.user.user;

import com.base.cn.platform.os.common.constants.CacheConstants;
import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.md5.MD5;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.action.ActionKey;
import com.base.cn.platform.os.common.utils.result.ResultUtil;
import com.base.cn.platform.os.entity.user.user.CusUser;
import com.base.cn.platform.os.service.course.cou.record.CoursePlayRecordService;
import com.base.cn.platform.os.service.exam.record.ExamQuestionRecordService;
import com.base.cn.platform.os.service.manage.config.SysConfigBiz;
import com.base.cn.platform.os.service.op.coupon.OpCouponCodeBiz;
import com.base.cn.platform.os.service.op.giftcard.OpGiftCardCodeBiz;
import com.base.cn.platform.os.service.order.order.OrderBiz;
import com.base.cn.platform.os.service.user.integral.CusUserIntegralBiz;
import com.base.cn.platform.os.service.user.loginLog.CusUserLoginLogBiz;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.extern.slf4j.Slf4j;
import net.oschina.j2cache.CacheObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * 用户登录Biz
 *
 * @author s.li
 * @create 2018-06-01-17:38
 */
@Service
@Slf4j
public class UserLoginBiz {
    private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
    @Autowired
    private CustomCacheChannel customCacheChannel;
    @Autowired
    private OpGiftCardCodeBiz opGiftCardCodeBiz;
    @Autowired
    private CusUserBiz cusUserBiz;
    @Autowired
    private CusUserIntegralBiz cusUserIntegralBiz;
    @Autowired
    private CusUserLoginLogBiz cusUserLoginLogBiz;
    @Autowired
    private OpCouponCodeBiz opCouponCodeBiz;
    @Autowired
    private SysConfigBiz sysConfigBiz;
    @Autowired
    private OrderBiz orderBiz;
    @Autowired
    private ExamQuestionRecordService examQuestionRecordService;
    @Autowired
    private CoursePlayRecordService coursePlayRecordService;

    /**
     * 设置用户登录
     * @param user     用户对象
     * @throws Exception
     */
    @Async
    @Transactional(rollbackFor =  IllegalArgumentException.class)
    public CusUser setUserLoginInfo(CusUser user, boolean isUserCard, BigDecimal userCardId){
        //如果是学员卡用户，修改学员卡状态
        if (ObjectUtils.isNotEmpty(user) && isUserCard && DataUtil.idIsNotNull(userCardId)) {
            opGiftCardCodeBiz.updateGiftCardUseTypeCode(userCardId, 2, user.getId());
        }
        user.setLastLoginTime(new Date());
        int loginNum = 0;
        if (user.getLoginNum()!=null&&user.getLoginNum()>0) {
            loginNum = user.getLoginNum();
        }
        user.setLoginNum(loginNum + 1);
        //更新用户
        cusUserBiz.updateById(user,null);
        //设置用户扩展数据
        return  user;
    }

    /**
     * 设置用户缓存
     * @param user 用户对象
     * @param autoThirty  缓存30天
     * @param loginForm 登录来源
     * @return  sessionId
     */
    public Map<String,Object> setUserCache(HttpServletRequest request, CusUser user,
                                           String sessionId,
                                           String autoThirty,
                                           String loginForm)throws IOException {
        if(user.getIsavalible().intValue() !=1){
            Map<String,Object> result = ResultUtil.ERROR("帐号已被冻结，暂不允许登录");
            result.put("FROZEN",true);
            return result;
        }
        TreeMap<String,String> configMap = sysConfigBiz.getSysConfigContext(ConfigName.ONOFF);
        String mobileSwitch = configMap.get("mobileSwitch");
        String subjectSwitch = configMap.get("subjectSwitch");
        Map<String,Object> resultMap=null;
        //手机未设置
        if(mobileSwitch.equals("ON") && (user.getMobileIsavalible()==null || user.getMobileIsavalible().intValue() != 1)){//重新缓存（临时缓存）
            customCacheChannel.set(J2CacheRegion.ONE_HOURS_REGION.getKey(),sessionId,user);
            resultMap = ResultUtil.SUCCESS("请绑定手机号");
            resultMap.put("status","MOBILE");
            resultMap.put("sessionId",sessionId);
        //如果没有设置专业/科目，则需要重新设置缓存
        }else if(subjectSwitch.equals("ON") && StringUtils.isEmpty(user.getNaturalSubjectIds())){ //（临时缓存）
            customCacheChannel.set(J2CacheRegion.ONE_HOURS_REGION.getKey(),sessionId,user);
            resultMap = ResultUtil.SUCCESS("请设置专业");
            resultMap.put("status","SUBJECT");
            resultMap.put("sessionId",sessionId);
        }
        if(resultMap!=null){
            return resultMap;
        }
        customCacheChannel.evict(J2CacheRegion.ONE_HOURS_REGION.getKey(),sessionId);
        //重新生成KEY
        sessionId = MD5.getMD5(StringUtils.getRandomString(32)+System.currentTimeMillis()+user.getId());
        Long aLong = DateUtils.currentToTwentyFour();
        J2CacheRegion.THIRTY_SIX_HOURS_REGION.setValue("10000, "+aLong+"s");
        try {
            //保存登录日志
            boolean isExists= customCacheChannel.exists(J2CacheRegion.THIRTY_SIX_HOURS_REGION.toString(), CacheConstants.LOGIN_COUNT+user.getId());
            cusUserLoginLogBiz.saveUserLoginLog(request,user.getId(),loginForm);
            //设置连续登录天数
            if (isExists) {
                CacheObject cacheObject = customCacheChannel.get(J2CacheRegion.THIRTY_SIX_HOURS_REGION.toString(), CacheConstants.LOGIN_COUNT+user.getId());
                Integer loginCount=(Integer) cacheObject.getValue();
                customCacheChannel.set(J2CacheRegion.THIRTY_SIX_HOURS_REGION.toString(), CacheConstants.LOGIN_COUNT+user.getId(), loginCount + 1);
            }else{
                customCacheChannel.set(J2CacheRegion.THIRTY_SIX_HOURS_REGION.toString(), CacheConstants.LOGIN_COUNT+user.getId(),  1);
            }
            //添加登录积分
            //检查是否登录
            boolean exists = customCacheChannel.exists(J2CacheRegion.THIRTY_SIX_HOURS_REGION.toString(), CacheConstants.LOGIN_START + user.getId());
            if(!exists){
                customCacheChannel.set(J2CacheRegion.THIRTY_SIX_HOURS_REGION.toString(), CacheConstants.LOGIN_START+user.getId(), true);
                cusUserIntegralBiz.addUserIntegralData(ActionKey.LOGIN,user.getId(), BigDecimal.ZERO,0,2);
            }
            //赠送用户生日优惠券
            opCouponCodeBiz.giveUserBirthdayCode(user.getId());
            //检查用户是否需要生成用户免费课程订单 减少延迟加载创建线程
            if(StringUtils.isNotEmpty( StringUtils.subHeadTailString(user.getCourseIds(),","))){
                orderBiz.userLoginFreeCourseOrder(user);
            }
          /*  //创建用户分表
            this.createUserShardingTable(user.getId());*/
        } catch (Exception e) {
            log.error("setUserCache()--error",e);
        }


        //正式缓存登录数据
        if(autoThirty.equals("true")){//缓存30天
            customCacheChannel.set(J2CacheRegion.THIRTY_DAY_REGION.getKey(),sessionId,gson.toJson(user));
            customCacheChannel.set(J2CacheRegion.THIRTY_DAY_REGION.getKey(),sessionId+ CacheConstants.SHARE_KEY_SUFFIX,MD5.getMD5(user.getId().toString())+"_"+user.getId());
        }else{//缓存1天
            customCacheChannel.set(J2CacheRegion.ONE_DAY_REGION.getKey(),sessionId,gson.toJson(user));
            customCacheChannel.set(J2CacheRegion.ONE_DAY_REGION.getKey(),sessionId+ CacheConstants.SHARE_KEY_SUFFIX,MD5.getMD5(user.getId().toString())+"_"+user.getId());
        }
        //缓存用户Token
        this.setUserToken(user.getId(),sessionId);
        resultMap = ResultUtil.SUCCESS("登录成功");
        resultMap.put("sessionId",sessionId);
        resultMap.put("administrator",user.isAdministrator());
        return resultMap;
    }

    /**
     * 设置用户Token
     * @param userId 用户ID
     * @param sessionId token
     */
    public void setUserToken(BigDecimal userId,String sessionId){
        log.info("++++++++++++++++++userId="+userId+",sessionId="+sessionId);
        customCacheChannel.set(J2CacheRegion.THIRTY_DAY_REGION.getKey(),userId.toString(),sessionId);
    }

   /* *//**
     * 创建用户分表
     * @param userId
     *//*
    public void createUserShardingTable(BigDecimal userId){
        //创建用户试题记录表
        examQuestionRecordService.createUserQuestionRecordTable(userId);
        //创建用户的学习记录表、学习明细表
        coursePlayRecordService.createUserPlayRecordTable(userId);
    }*/
}
